//
//  THttpTool.h
//  TProject
//
//  Created by txj on 2016/12/23.
//  Copyright © 2016年 txj. All rights reserved.
//
//  网络请求工具类：负责整个项目的所有http请求

#import <Foundation/Foundation.h>


typedef NS_ENUM(NSInteger, TNetworkStatus) {
    kTNetworkStatusStatusUnknown          = -1,//未知网络
    kTNetworkStatusNotReachable     = 0,//网络无连接
    kTNetworkStatusReachableViaWWAN = 1,//2，3，4G网络
    kTNetworkStatusReachableViaWiFi = 2,//WIFI网络
};

typedef NS_ENUM(NSUInteger, TRequestType) {
    kTRequestTypeJSON = 1, // 默认
    kTRequestTypePlainText  = 2 // 普通text/html
};
typedef NS_ENUM(NSUInteger, TResponseType) {
    kTResponseTypeJSON = 1, // 默认
    kTResponseTypeXML  = 2, // XML
    // 特殊情况下，一转换服务器就无法识别的，默认会尝试转换成JSON，若失败则需要自己去转换
    kTResponseTypeData = 3
};

/* 当request成功后的 TRequestSuccessBlock */
typedef void (^TRequestSuccessBlock)(id responseObj);
/* 请求失败的时候 */
typedef void (^TRequestFailureBlock)(NSError *error);
/* 请求成功 经过处理的有效block (子类写网络请求的时候用这个block) */
typedef void (^TResponseHandler)(id dataObj, NSError *error);


/**
 文件下载进度

 @param bytesRead 已下载
 @param totalBytesRead 总共
 */
typedef void (^TDownloadProgress)(int64_t bytesRead,
int64_t totalBytesRead);

typedef TDownloadProgress TGetProgress;
typedef TDownloadProgress TPostProgress;

/*!
 *
 *  上传进度
 *
 *  @param bytesWritten              已上传的大小
 *  @param totalBytesWritten         总上传大小
 */
typedef void (^TUploadProgress)(int64_t bytesWritten,
int64_t totalBytesWritten);


// 请勿直接使用NSURLSessionDataTask,以减少对第三方的依赖
// 所有接口返回的类型都是基类NSURLSessionTask，若要接收返回值
// 且处理，请转换成对应的子类类型
typedef NSURLSessionTask TURLSessionTask;

/*!
 *
 *  基于AFNetworking的网络层封装类.
 *
 *  @note 这里只提供公共api
 */

@interface THttpTool : NSObject

/*!
 *  用于指定网络请求接口的基础url，如：
 *  通常在AppDelegate中启动时就设置一次就可以了。如果接口有来源
 *  于多个服务器，可以调用更新
 *
 *  @param baseUrl 网络接口的基础url
 */
+ (void)updateBaseUrl:(NSString *)baseUrl;
+ (NSString *)baseUrl;

//取消所有的请求
+ (void)cancelAllRequest;

/*!
 *  配置请求格式，默认为JSON。如果要求传XML或者PLIST，请在全局配置一下
 *
 *  @param requestType 请求格式，默认为JSON
 *  @param responseType 响应格式，默认为JSO，
 *  @param shouldAutoEncode YES or NO,默认为NO，是否自动encode url
 *  @param shouldCallbackOnCancelRequest 当取消请求时，是否要回调，默认为YES
 */
+ (void)configRequestType:(TRequestType)requestType
             responseType:(TResponseType)responseType
      shouldAutoEncodeUrl:(BOOL)shouldAutoEncode
  callbackOnCancelRequest:(BOOL)shouldCallbackOnCancelRequest;

/*!
 *
 *  配置公共的请求头，只调用一次即可，通常放在应用启动的时候配置就可以了
 *
 *  @param httpHeaders 只需要将与服务器商定的固定参数设置即可
 */
+ (void)configCommonHttpHeaders:(NSDictionary *)httpHeaders;


/**
 *	设置请求超时时间，默认为60秒
 *
 *	@param timeout 超时时间
 */
+ (void)setTimeout:(NSTimeInterval)timeout;
/**
 *	当检查到网络异常时，是否从从本地提取数据。默认为NO。一旦设置为YES,当设置刷新缓存时，
 *  若网络异常也会从缓存中读取数据。同样，如果设置超时不回调，同样也会在网络异常时回调，除非
 *  本地没有数据！
 *
 *	@param shouldObtain	YES/NO
 */
+ (void)obtainDataFromLocalWhenNetworkUnconnected:(BOOL)shouldObtain;

/**
 *	默认只缓存GET请求的数据，对于POST请求是不缓存的。如果要缓存POST获取的数据，需要手动调用设置
 *  对JSON类型数据有效，对于PLIST、XML不确定！
 *
 *	@param isCacheGet			默认为YES
 *	@param shouldCachePost	默认为NO
 */
+ (void)cacheGetRequest:(BOOL)isCacheGet shoulCachePost:(BOOL)shouldCachePost;

/**
 *	获取缓存总大小/bytes
 *
 *	@return 缓存大小
 */
+ (unsigned long long)totalCacheSize;

/**
 *	默认不会自动清除缓存，如果需要，可以设置自动清除缓存，并且需要指定上限。当指定上限>0M时，
 *  若缓存达到了上限值，则每次启动应用则尝试自动去清理缓存。
 *
 *	@param mSize				缓存上限大小，单位为M（兆），默认为0，表示不清理
 */
+ (void)autoToClearCacheWithLimitedToSize:(NSUInteger)mSize;

/**
 *	清除缓存
 */
+ (void)clearCaches;

+ (id)cahceResponseWithURL:(NSString *)url parameters:params;

/**
 get请求

 @param url 接口地址
 @param refreshCache 是否刷新缓存
 @param success 成功的回调
 @param fail 失败回调
 @return 返回值
 */
+ (TURLSessionTask *)getWithUrl:(NSString *)url
                     refreshCache:(BOOL)refreshCache
                          success:(TRequestSuccessBlock)success
                             fail:(TRequestFailureBlock)fail;
// 多一个params参数
+ (TURLSessionTask *)getWithUrl:(NSString *)url
                     refreshCache:(BOOL)refreshCache
                           params:(NSDictionary *)params
                          success:(TRequestSuccessBlock)success
                             fail:(TRequestFailureBlock)fail;
// 多一个带进度回调
+ (TURLSessionTask *)getWithUrl:(NSString *)url
                     refreshCache:(BOOL)refreshCache
                           params:(NSDictionary *)params
                         progress:(TGetProgress)progress
                          success:(TRequestSuccessBlock)success
                             fail:(TRequestFailureBlock)fail;

/*!
 *
 *  POST请求接口，若不指定baseurl，可传完整的url
 *
 *  @param url     接口路径，如/path/getArticleList
 *  @param params  接口中所需的参数，如@{"categoryid" : @(12)}
 *  @param success 接口成功请求到数据的回调
 *  @param fail    接口请求数据失败的回调
 *
 *  @return 返回的对象中有可取消请求的API
 */
+ (TURLSessionTask *)postWithUrl:(NSString *)url
                      refreshCache:(BOOL)refreshCache
                            params:(NSDictionary *)params
                           success:(TRequestSuccessBlock)success
                              fail:(TRequestFailureBlock)fail;
+ (TURLSessionTask *)postWithUrl:(NSString *)url
                      refreshCache:(BOOL)refreshCache
                            params:(NSDictionary *)params
                          progress:(TPostProgress)progress
                           success:(TRequestSuccessBlock)success
                              fail:(TRequestFailureBlock)fail;


/*!
 *  下载文件
 *
 *  @param url           下载URL
 *  @param saveToPath    下载到哪个路径下
 *  @param progressBlock 下载进度
 *  @param success       下载成功后的回调
 *  @param failure       下载失败后的回调
 */
+ (TURLSessionTask *)downloadWithUrl:(NSString *)url
                            saveToPath:(NSString *)saveToPath
                              progress:(TDownloadProgress)progressBlock
                               success:(TRequestSuccessBlock)success
                               failure:(TRequestFailureBlock)failure;



/**
 文件上传

 @param url 接口地址
 @param fileData 文件
 @param params 业务产生
 @param fileName 文件名
 @param mimeType 文件类型
 @param uploadProgress 上传进度
 @param successHandler 成功
 @param failureHandler 失败
 */
+(void)uploadFileWithUrl:(NSString *)url WithData:(NSData *)fileData params:(id)params fileName:(NSString *)fileName mineType:(NSString *)mimeType progress:(void (^)(NSProgress *uploadProgress))uploadProgress success:(TRequestSuccessBlock)successHandler failure:(TRequestFailureBlock)failureHandler;


+(void)uploadFileWithUrl:(NSString *)url WithDataArray:(NSArray *)fileDataArray params:(id)params fileNames:(NSArray *)fileNames mineType:(NSString *)mimeType progress:(void (^)(NSProgress *uploadProgress))uploadProgress success:(TRequestSuccessBlock)successHandler failure:(TRequestFailureBlock)failureHandler;
@end
